/*
 * Copyright 2009 Jeremy Thomerson
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* FORM LEVEL HANDLER OBJECTS: */
function AbstractFormHandler() {
	this.form = null;
}

AbstractFormHandler.prototype.setForm = function(form) {
	this.form = $(form);
};

AbstractFormHandler.prototype.execute = function() {
	this.executeBegin();
	var handler = this;

	var jform = this.form;
	var elements = $(jform.data('jElements'));

	elements.each(function() {
		var jelem = $(this);
		var messages = $(jelem.data('jValErrorMessages'));
		var hasMessages = messages.size() > 0;
		handler.formElementBegin(jelem, hasMessages);
		messages.each(function() {
			handler.message(this);
		});
		handler.formElementEnd(jelem, hasMessages);
	});
	
	this.executeEnd();
};

// these methods are intended to be overridden:
AbstractFormHandler.prototype.executeBegin = function() {};
AbstractFormHandler.prototype.formElementBegin = function(jelem, hasMessages) {};
AbstractFormHandler.prototype.message = function(message) {};
AbstractFormHandler.prototype.formElementEnd = function(jelem, hasMessages) {};
AbstractFormHandler.prototype.executeEnd = function() {};

function FormFeedbackPanel(feedbackElement, showFieldNames) {
	this.feedbackElement = feedbackElement;
	this.showFieldNames = (showFieldNames == undefined ? true : showFieldNames);
	AbstractFormHandler.call(this);
}
FormFeedbackPanel.prototype = new AbstractFormHandler();

FormFeedbackPanel.prototype.executeBegin = function() {
	this.html = '<span class="failedMessage">There were errors in your form:</span>';
	if (this.showFieldNames) {
		this.html += '<ul class="feedbackPanelElementNames">';
	} else {
		this.html += '<ul class="feedbackPanelErrors">';
	}
};
FormFeedbackPanel.prototype.formElementBegin = function(jelem, hasMessages) {
	if (hasMessages && this.showFieldNames) {
		this.html += '<li>' + jelem.data('jValFriendlyName') + '</li>';
		this.html += '<ul class="feedbackPanelErrors">';
	}
};
FormFeedbackPanel.prototype.message = function(message) {
	this.html += '<li>' + message + '</li>';
};
FormFeedbackPanel.prototype.formElementEnd = function(jelem, hasMessages) {
	if (hasMessages && this.showFieldNames) {
		this.html += '</ul>';
	}
};
FormFeedbackPanel.prototype.executeEnd = function() {
	this.html += '</ul>';
	$(this.feedbackElement).html(this.html);
};

/* ELEMENT LEVEL HANDLER OBJECTS: */
function AbstractElementHandler() {
}

AbstractElementHandler.prototype.execute = function(jelem) {
	console.warn(this.message + ' (the execute method of your handler should be overridden)');
};

function ChangeClassHandler(onSuccessClass, onFailureClass) {
	this.onSuccessClass = onSuccessClass;
	this.onFailureClass = onFailureClass;
	AbstractElementHandler.call(this);
}
ChangeClassHandler.prototype = new AbstractFormHandler();

ChangeClassHandler.prototype.execute = function(jelem, succeeded) {
	jelem.removeClass(succeeded ? this.onFailureClass : this.onSuccessClass);
	jelem.addClass(succeeded ? this.onSuccessClass : this.onFailureClass);
};

function MessagePerFieldHandler() {
	AbstractElementHandler.call(this);
}
MessagePerFieldHandler.DIV_DATA_NAME	= 'MPFGMessageDiv';
MessagePerFieldHandler.SLIDE_SPEED		= 500;
MessagePerFieldHandler.prototype = new AbstractFormHandler();

MessagePerFieldHandler.prototype.execute = function(jelem, succeeded) {
	console.debug('MessagePerFieldHandler');
	if (succeeded) {
		var olddiv = jelem.data(MessagePerFieldHandler.DIV_DATA_NAME);
		if (olddiv) {
			olddiv.slideUp(MessagePerFieldHandler.SLIDE_SPEED);
		}
		// TODO: clear the messages
	} else {
		var olddiv = jelem.data(MessagePerFieldHandler.DIV_DATA_NAME);
		var div = $('<div class="formElementMessage"></div>');
		var messages = $(jelem.data('jValErrorMessages'));
		this.addMessages(div, messages);
		jelem.data(MessagePerFieldHandler.DIV_DATA_NAME, div);
		if (olddiv) {
			olddiv.replaceWith(div);
		} else {
			div.hide(0);
			jelem.parent().append(div);
			div.slideDown(MessagePerFieldHandler.SLIDE_SPEED);
		}
	}
};

MessagePerFieldHandler.prototype.addMessages = function(div, messages) {
	var ul = $('<ul></ul>');
	messages.each(function() {
		var li = $('<li>' + this + '</li>');
		ul.append(li);
	});
	div.append(ul);
};
